<!-- 角色设置 -->
<template>
  <div>
    <card>
      <el-form inline :model="listQuery" slot="header">
        <el-form-item label="角色查询：">
          <el-input clearable v-permission="$common.directiveButton(this, 'serach')" v-model="listQuery.roleName" placeholder="请输入角色名称" @keyup.enter.native="handleFilter">
            <el-button v-permission="$common.directiveButton(this, 'serach')" slot="append" icon="el-icon-search" @click="handleFilter"></el-button>
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-button v-permission="$common.directiveButton(this, 'add')" type="primary" icon="el-icon-edit" @click="handleAddRole">新增</el-button>
        </el-form-item>
      </el-form>

      <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%;">
        <el-table-column prop="roleId" label="角色ID"></el-table-column>
        <el-table-column prop="roleName" label="角色名称"></el-table-column>
        <el-table-column prop="remark" label="备注"></el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column align="center" label="操作" width="160">
          <template slot-scope="scope">
            <el-button type="primary" size="small" @click="handleEdit(scope)">修改</el-button>
            <el-button type="danger" size="small" @click="handleDelete(scope)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
    </card>
    <el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'修改权限':'新增权限'">
      <el-form :model="role" label-width="80px" label-position="left" style="width:600px;margin-left: 50px;">
        <el-form-item label="角色名称">
          <el-input v-model="role.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="role.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入备注" />
        </el-form-item>
        <el-form-item label="权限功能">
          <div style="min-height: 220px;max-height:600px; overflow:auto">
            <!-- <div style="height:800px"> -->
            <el-tree ref="tree" :data="routesData" :props="defaultProps" show-checkbox default-expand-all check-strictly node-key="menuId" class="permission-tree" @check-change="checkChange"></el-tree>
            <!-- </div> -->
          </div>
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button type="danger" @click="dialogVisible=false">取消</el-button>
        <el-button type="primary" @click="confirmRole">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Pagination from "@/components/Pagination";
import Card from '@/components/Card/index.vue'
import path from "path";
import { mapGetters } from "vuex";

const defaultRole = {
  deptId: "1",
  roleName: "",
  remark: "",
  menuIdList: [],
};
export default {
  name: "role",
  // import引入的组件需要注入到对象中才能使用
  components: {
    Pagination,
    Card
  },
  data() {
    return {
      total: 0,
      listLoading: false,
      listQuery: {
        roleName: undefined,
        page: 1,
        limit: 10,
      },
      list: [],
      // 弹框
      dialogVisible: false,
      role: Object.assign({}, defaultRole),
      // 权限树
      routes: [],
      dialogType: "新增",
      defaultProps: {
        children: "children",
        label: "title",
      },
    };
  },
  // 计算属性
  computed: {
    ...mapGetters('permission', ['getButtons']),
    routesData() {
      return this.routes;
    },
  },
  // 监听属性
  watch: {},
  mounted() {
    // log(this.$store.state.permission.addRoutes, this.getButtons);
    this.getList();
    this.getRoutes();
  },
  methods: {
    // 搜索
    handleFilter() {
      this.listQuery.page = 1;
      this.getList();
    },
    // 获取数据
    getList() {
      this.listLoading = true;
      this.$http.post("/sys/role/lists", this.listQuery).then((res) => {
        const { page } = res;
        this.total = page.totalCount;
        this.list = page.list;

        this.listLoading = false;
      });
    },
    // 处理菜单树
    async getRoutes() {
      // 获取路由
      this.serviceRoutes = this.$store.state.permission.addRoutes;
      let tree = this.generate(this.serviceRoutes);

      // log(this.serviceRoutes, tree)
      // 递归添加按钮
      for (let [key, value] of Object.entries(this.getButtons)) {
        if (value instanceof Array)
          value.forEach((item) => {
            item.title = item.name;
          });
      }
      // 递归添加按钮
      await this.buttonTree(tree);
      // 递归为所有的按钮添加父节点
      await this.parentIdTree(tree);
      this.routes = tree;
      // console.dir(tree);
    },
    buttonTree(tree) {
      tree.forEach((item) => {
        if (item?.children?.length > 0) {
          if (item?.name && this.getButtons[item.name]) {
            item.children.push(this.getButtons[item.name]);
          }
          this.buttonTree(item.children);
        } else {
          if (item?.name) {
            if (this.getButtons[item.name]) {
              item.children = this.getButtons[item.name];
            }
          }
        }
      });
    },
    parentIdTree(tree, parent = {}) {
      tree.forEach((item) => {
        if (parent?.menuId) {
          item["parentId"] = parent.menuId;
        }

        if (item?.children) {
          this.parentIdTree(item.children, item);
        }
      });
    },
    generate(routes, basePath = "/") {
      const res = [];

      for (let route of routes) {
        // skip some route

        // 过滤所有hidden页面
        // if (route.hidden) {
        //   continue;
        // }

        // 过滤404页面
        if (route.hide) {
          continue;
        }
        const onlyOneShowingChild = this.onlyOneShowingChild(
          route.children,
          route
        );
        if (route.children && onlyOneShowingChild && !route.alwaysShow) {
          route = onlyOneShowingChild;
        }

        const data = {
          path: path.resolve(basePath, route.path),
          title: route.meta && route.meta.title,
          name: route.name,
          menuId: route.menuId,
        };

        // recursive child routes
        if (route.children) {
          data.children = this.generate(route.children, data.path);
        }
        res.push(data);
      }
      return res;
    },
    onlyOneShowingChild(children = [], parent) {
      let onlyOneChild = null;
      const showingChildren = children.filter((item) => !item.hidden);

      // When there is only one child route, the child route is displayed by default
      if (showingChildren.length === 1) {
        onlyOneChild = showingChildren[0];
        onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path);
        return onlyOneChild;
      }

      // Show parent if there are no child route to display
      if (showingChildren.length === 0) {
        onlyOneChild = {
          ...parent,
          path: "",
          noShowingChildren: true,
        };
        return onlyOneChild;
      }

      return false;
    },

    checkChange(data, check) {
      // 父节点操作
      if (data?.parentId) {
        if (check === true) {
          // 如果选中，设置父节点为选中
          this.$refs.tree.setChecked(data.parentId, true);
        }
      }

      // 取消消除所有子节点
      if (check === false) {
        this.checkFalse(data);
      }
    },
    checkFalse(tree) {
      if (tree?.children) {
        tree.children.forEach((item) => {
          this.$refs.tree.setChecked(item.menuId, false);
          if (item?.children) {
            this.checkFalse(item);
          }
        });
      }
    },

    // 新增角色
    handleAddRole() {
      // 滞空数据
      this.role = Object.assign({}, defaultRole);
      // 滞空选择的树
      if (this.$refs.tree) {
        this.$refs.tree.setCheckedNodes([]);
      }
      this.buttonRole = [];
      this.dialogType = "新增";
      this.dialogVisible = true;
    },

    // 修改
    handleEdit({ row }) {
      this.$http.get("/sys/role/info/" + row.roleId).then((res) => {
        this.dialogType = "edit";
        this.dialogVisible = true;
        this.role = res.role;
        this.$nextTick(() => {
          log(res.role.menuIdList);
          this.$refs.tree.setCheckedKeys(res.role.menuIdList);
        });
      });
    },
    // 删除
    handleDelete({ row }) {
      this.$confirm("此操作不可逆转, 是否确定删除该角色?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$http.post("/sys/role/delete", [row.roleId + ""]).then((res) => {
            // console.log(res);
            this.handleFilter();
            this.$message({
              type: "success",
              message: "删除成功!",
            });
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    // 确认
    confirmRole() {
      // log(this.$refs.tree.getCheckedKeys());
      // log(this.$refs.tree.getHalfCheckedKeys());

      this.role.menuIdList = [
        ...this.$refs.tree.getCheckedKeys(),
        ...this.$refs.tree.getHalfCheckedKeys(),
      ];

      let url = "";
      if (this.role?.roleId) {
        url = "/sys/role/update";
      } else {
        url = "/sys/role/save";
      }

      this.$http.post(url, this.role).then((res) => {
        // log(res);
        this.dialogVisible = false;
        this.handleFilter();
      });
    },
  },
};
</script>
<style lang='scss' scoped>
.custom-tree-node {
  height: 40px;
}
</style>